package com.malty.utils;

import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;

/**
 * 网络工具类
 *
 * @author malty
 */
public class NetUtil {
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST = "127.0.0.1";
    private static final String X_FORWARDED_FOR = "x-forwarded-for";
    private static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";
    private static final String PROXY_CLIENT_IP = "Proxy-Client-IP";
    private static final String COMMA = ",";

    private NetUtil() {
    }

    /**
     * 获取客户端 IP 地址
     *
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader(X_FORWARDED_FOR);
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader(PROXY_CLIENT_IP);
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader(WL_PROXY_CLIENT_IP);
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if (LOCALHOST.equals(ip)) {
                // 根据网卡取本机配置的 IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (inet != null) {
                    ip = inet.getHostAddress();
                }
            }
        }
        // 多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if (ip != null && ip.length() > 15) {
            if (ip.indexOf(COMMA) > 0) {
                ip = ip.substring(0, ip.indexOf(COMMA));
            }
        }
        if (ip == null) {
            return LOCALHOST;
        }
        return ip;
    }

    @Slf4j
    // @Component
    public static class OKHttpUtil {
        private static OkHttpClient okHttpClient;

        @Autowired
        public OKHttpUtil(OkHttpClient okHttpClient) {
            OKHttpUtil.okHttpClient = okHttpClient;
        }

        public static void setOkHttpClient(OkHttpClient okHttpClient) {
            OKHttpUtil.okHttpClient = okHttpClient;
        }

        /**
         * get
         *
         * @param url     请求的url
         * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
         * @return
         */
        public static String get(String url, Map<String, String> queries, String charset) throws IOException {
            String responseBody = "";
            String query = buildQuery(queries, charset, url);
            Request request = new Request.Builder().url(query).build();
            Response response = null;
            try {
                response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                    return response.body().string();
                }
            } catch (SocketTimeoutException socketException) {
                // log.warn(MessageCode.REQUEST_TIME_OUT.getMessage());
            } catch (Exception e) {
                log.warn("okhttp3 put error >> ex = {}", e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            return responseBody;
        }

        public static String buildQuery(Map<String, String> params, String charset, String url) throws IOException {
            if (params == null || params.isEmpty()) {
                return null;
            }
            String responseBody = "";
            StringBuffer sb = new StringBuffer(url);
            boolean firstFlag = true;
            Iterator iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), charset));
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "=" + URLEncoder.encode(entry.getValue().toString(), charset));
                }
            }
            return sb.toString();
        }

        /**
         * Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"} 参数一：请求Url 参数二：请求的JSON
         * 参数三：请求回调
         */
        public static String postJsonParams(String url, String jsonParams) {
            String responseBody = "";
            RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
            Request request = new Request.Builder().url(url).post(requestBody).build();
            Response response = null;
            try {
                response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                    return response.body().string();
                }
            } catch (SocketTimeoutException socketException) {
                // log.warn(MessageCode.REQUEST_TIME_OUT.getMessage());
            } catch (Exception e) {
                log.warn("okhttp3 post error >> ex = {}", e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            return responseBody;
        }

        public static String postJsonParamsUsingurlencoded(String url, String jsonParams) {
            String responseBody = "";
            RequestBody requestBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"), jsonParams);
            Request request = new Request.Builder().url(url).post(requestBody).build();
            Response response = null;
            try {
                response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                    return response.body().string();
                }
            } catch (Exception e) {
                log.warn("okhttp3 post error >> ex = {}", e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            return responseBody;
        }

    }
}
